#ifndef NODE_H
#define NODE_H


#include "Framework/Prerequisites.h"
#include "Framework/StableHeaders.h"



namespace tyro
{
	namespace Scene
	{
		class Node
		{
		public:

			 
			typedef ::stdext::hash_map<String, Node*> ChildNodeMap;

			Node();
			Node(String name);

			virtual Node* CreateChildNode(const String& name, const Math::Vector3f& translation = Math::Vector3f::ZERO,
				const Math::Quaternionf& rotation = Math::Quaternionf::IDENTITY);
			virtual Node* CreateChildNode(const Math::Vector3f& translation = Math::Vector3f::ZERO,
				const Math::Quaternionf& rotation = Math::Quaternionf::IDENTITY);


			virtual void Update();
			virtual void UpdateFromParent() const;
			virtual void UpdateFromParentImpl() const;

			virtual const Math::Matrix4f& GetFullWorldTransform(void) const;


			virtual void SetTranslation( FLOAT_32  x, FLOAT_32 y, FLOAT_32 z );
			virtual void SetTranslation( Math::Vector3f vec );
			virtual void Rotate(const Math::Vector3f axis, const Math::Radianf angle, TransformSpace relativeTo = TS_LOCAL);
			virtual void Rotate(const Math::Quaternionf& rotation, TransformSpace relativeTo = TS_LOCAL);
			virtual void SetScale( FLOAT_32  x, FLOAT_32 y, FLOAT_32 z );
			virtual void SetScale( Math::Vector3f vec );

			void FlagUpdate();
			virtual void AddChild( Node* child );
			virtual Node* CreateChildImpl(void) = 0;
			virtual Node* CreateChildImpl(const String& name) = 0;
			const String& GetName( void ) const;
			virtual void SetParent( Node* parent );
			virtual const Math::Vector3f& GetDerivedTranslation(void) const;
			virtual const Math::Quaternionf& GetDerivedRotation( void ) const;
			virtual const Math::Vector3f& GetDerivedScale(void) const;
		protected:

			Node*				parent;

			String				name;
			ChildNodeMap		children;
			Math::Quaternionf	rotation;
			Math::Vector3f		scale;
			Math::Vector3f		translation;

			static Framework::NameGenerator	nameGen;

			mutable	Math::Quaternionf	derivedRotation;
			mutable	Math::Vector3f		derivedScale;
			mutable Math::Vector3f		derivedTranslation;

			mutable	bool transformOutOfDate;
			mutable Math::Matrix4f derivedTransform;
			mutable bool NeedsParentUpdate;
		private:
		};
	}
}
#endif